package com.springsource.a05CommonBeanFactoryPostProcessor;

import cn.hutool.core.util.StrUtil;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.type.MethodMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;

import java.util.Map;
import java.util.Set;

// 解析@Bean注解
public class MyConfigurationClassPostProcessor2 implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        CachingMetadataReaderFactory cachingMetadataReaderFactory = new CachingMetadataReaderFactory();
        try {
            // 解析config中的注解
            MetadataReader metadataReader = cachingMetadataReaderFactory.getMetadataReader(new ClassPathResource("com/springsource/a05CommonBeanFactoryPostProcessor/Config.class"));
            // 找出有@Bean的方法
            Set<MethodMetadata> annotatedMethods = metadataReader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
            for (MethodMetadata annotatedMethod : annotatedMethods) {
                BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition();
                // 设置自动装配的模式，工厂方法和构造方法都选这个
                beanDefinitionBuilder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
                // 选择工厂方法，哪个bean的哪个方法名
                beanDefinitionBuilder.setFactoryMethodOnBean(annotatedMethod.getMethodName(), "config");
                // 解析@Bean注解的属性
                Map<String, Object> annotationAttributes = annotatedMethod.getAnnotationAttributes(Bean.class.getName());
                if (StrUtil.isNotEmpty(annotationAttributes.get("initMethod").toString())) {
                    beanDefinitionBuilder.setInitMethodName(annotationAttributes.get("initMethod").toString());
                }
                // 注册BeanDefinition
                ((DefaultListableBeanFactory) beanFactory).registerBeanDefinition(annotatedMethod.getMethodName(), beanDefinitionBuilder.getBeanDefinition());
            }
        } catch (Exception e) {
             e.printStackTrace();
        }


    }
}
